

pub trait Draw {
    fn draw(&self);
}

struct Button {
}
impl Draw for Button  {
    fn draw(&self) {
        println!("this is Button");
    }
}
struct SelectBox {
}
impl Draw for SelectBox {
    fn draw(&self) {
        println!("this is SelectBox");
    }
}

mod object_style{

pub struct Screen {
    pub windows: Vec<Box<dyn super::Draw>> //NOTE::
}

impl Screen {
    pub fn run(&self) {
        self.windows.iter().for_each(|x| x.draw());
    }
}
}//mod object_style

mod generic_style {

//same function for object_style
pub struct Screen<T> 
where T: super::Draw + ?Sized
{
    pub windows: Vec<Box<T>>, //NOTE::
}

impl<T> Screen<T> 
where T: super::Draw + ?Sized
{
    pub fn run(&self) {
        self.windows.iter().for_each(|x| x.draw());
    }
}

}//mod generic_style

mod pure_generic_style {

pub struct Screen<T: super::Draw> {
    pub windows: Vec<T>, //NOTE::
}

impl<T: super::Draw> Screen<T> {
    pub fn run(&self) {
        self.windows.iter().for_each(|x| x.draw());
    }
}

}//mod pure_generic_style



#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn generic_style_screen() {
        let screen = generic_style::Screen::<dyn Draw> {
            windows: vec! [
                Box::new(Button{}),
                Box::new(Button{}),
                Box::new(Button{}),
                Box::new(SelectBox{})
            ]
        };
        screen.run();
    }

    #[test]
    fn pure_generic_style_screen(){
        let screen = pure_generic_style::Screen::<Button> {
            windows: vec! [
                Button{},
                Button{},
                Button{},
            ]
        };
        screen.run();
    }
    #[test]
    fn object_style_screen(){
        let screen = object_style::Screen{
            windows: vec! [
                Box::new(Button{}),
                Box::new(Button{}),
                Box::new(Button{}),
            ]
        };
        screen.run();
    }
}
